package Map;

import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Random;

import Main.GamePanel;
import Utils.Constantes;
import Utils.TipoCoord;
import Utils.TipoWave;
import enemies.Enemy;


public class TileMap {
    
    public Image TileSet = null;
    String nome;
    int MapX;
    int MapY;
    int NTileX,NTileY;
    int Largura = 60;
    int Altura = 50;
    int TilePLinhaTileset;
    
    public int [][]mapa;
	public int [][]mapa2; 
	public int numPaths = -1;
	public ArrayList<ArrayList<TipoCoord>> listaPaths;
	public ArrayList<TipoWave> listaWaves;
	public int quantidadeTotalInimigos;
	private Random rand = new Random();
	
	public int waveAtual = 0;
	
	public BufferedImage buffer = null; 
            		
    public TileMap(Image tileset,int tilestelaX,int tilestelaY, String nomeDoMapa){
        NTileX = tilestelaX;
        NTileY = tilestelaY;
        TileSet = tileset;
        MapX = 0;
        MapY = 0;
        TilePLinhaTileset = TileSet.getWidth(null) >>4;
        nome = nomeDoMapa;
    }
    
    public void AbreMapa(String nomemapa){
            	
	try{
    		InputStream In = getClass().getResourceAsStream(nomemapa);
    		
    		//System.out.println(" In "+In.available());
    		
    		DataInputStream data = new DataInputStream(In); 
    		
    		
    	
    		@SuppressWarnings("unused")
			int Versao = data.readInt(); // l� Versao
        	Largura = ReadCInt(data);    // l� Largura
        	Altura = ReadCInt(data);	// l� Largura
        	
        	//System.out.println(" Largura "+Largura);
        	
           	//System.out.println(" Altura "+Altura);
           	
        	@SuppressWarnings("unused")
			int ltilex =  ReadCInt(data);// l� Larg Tile
        	@SuppressWarnings("unused")
			int ltiley =  ReadCInt(data);// l� Altura Tile
        	
        	//System.out.println(" ltilex "+ltilex);
        	
           ////	System.out.println(" ltiley "+ltiley);
           	
        	byte nome[] = new byte[32]; 

        	data.read(nome,0,32);       // l� Nome Tilemap
        	data.read(nome,0,32); 
        	
        	int numLayers =  ReadCInt(data);// l� numero de Layers
        	@SuppressWarnings("unused")
			int numTiles =  ReadCInt(data);// l� numero de Tiles
        	
           	//System.out.println(" numLayers "+numLayers);
           //	System.out.println(" numTiles "+numTiles);
        	
            int BytesPorTiles =  ReadCInt(data); // l� numero de bytes por tile;
            
//           	System.out.println(" BytesPorTiles "+BytesPorTiles);
           	
            @SuppressWarnings("unused")
			int vago1 =  ReadCInt(data); // l� vago;
            @SuppressWarnings("unused")
            int vago2 =  ReadCInt(data); // l� vago;            
            
        	mapa = new int[Altura][Largura];
        	mapa2 = new int[Altura][Largura];
        	
        	if(BytesPorTiles==1){
                
        	    for(int j = 0; j < Altura; j++){            
                    for(int i = 0; i < Largura; i++){
                    	int dado;
                    	
                    	int b1 = data.readByte();
                    	int b2 = data.readByte();            	
                    	
                    	dado = ((int)b1&0x00ff)|(((int)b2&0x00ff)<<8);            	
                    	
                    	mapa[j][i] = dado;	            	
                    	//System.out.println(" "+mapa[j][i]);            	
                    }
                }
        	    if(numLayers==2){
	        	    for(int j = 0; j < Altura; j++){            
	                    for(int i = 0; i < Largura; i++){
	                    	int dado;
	                    	
	                    	int b1 = data.readByte();
	                    	int b2 = data.readByte();            	
	                    	
	                    	dado = ((int)b1&0x00ff)|(((int)b2&0x00ff)<<8);            	
	                    	
	                    	mapa2[j][i] = dado;	            	
	                    	//System.out.println(" "+mapa2[j][i]);            	
	                    }
	                }
        	    }
                
        	}else if(BytesPorTiles==2){
        	    for(int j = 0; j < Altura; j++){            
                    for(int i = 0; i < Largura; i++){
                    	int dado;
                    	
                    	
                    	int b1 = data.readByte();
                    	int b2 = data.readByte(); 
                    	int b3 = data.readByte(); 
                    	int b4 = data.readByte();                     	
                    	
                    	dado = ((int)b1&0x00ff)|(((int)b2&0x00ff)<<8)|(((int)b3&0x00ff)<<16)|(((int)b4&0x00ff)<<24);           	
                    	
                    	mapa[j][i] = dado;	            	
                    	//System.out.println(" "+mapa[j][i]);            	
                    }
                }
        	    if(numLayers==2){
	        	    for(int j = 0; j < Altura; j++){            
	                    for(int i = 0; i < Largura; i++){
	                    	int dado;
	                    	
	                    	int b1 = data.readByte();
	                    	int b2 = data.readByte(); 
	                    	int b3 = data.readByte(); 
	                    	int b4 = data.readByte();                     	
	                    	
	                    	dado = ((int)b1&0x00ff)|(((int)b2&0x00ff)<<8)|(((int)b3&0x00ff)<<16)|(((int)b4&0x00ff)<<24);            	
	                    	
	                    	mapa2[j][i] = dado;	            	
	                    	//System.out.println(" "+mapa2[j][i]);            	
	                    }
	                } 
        	    }
        	}else{
        	    for(int j = 0; j < Altura; j++){            
                    for(int i = 0; i < Largura; i++){
                    	int dado;
                    	
                    	int b1 = data.readByte(); 
                    	
                    	//System.out.println(" "+b1);
                    	
                    	dado = ((int)b1&0x00ff);            	
                    	
                    	mapa[j][i] = dado;	            	
                    	//System.out.println(" "+mapa[j][i]);            	
                    }
                }
        	    if(numLayers==2){
	        	    for(int j = 0; j < Altura; j++){            
	                    for(int i = 0; i < Largura; i++){
	                    	int dado;
	                    	
	                    	int b1 = data.readByte(); 
	                    	
	                    	dado = ((int)b1&0x00ff);            	
	                    	
	                    	mapa2[j][i] = dado;	            	
	                    	//System.out.println(" "+mapa2[j][i]);            	
	                    }
	                } 
        	    }
        	}
  		

        
        
       	data.close();
    		
    	In.close();
    		
	    }//fim try
	    catch (Exception e)
	    {
	    	e.printStackTrace();
	      System.out.println(e.getMessage()+ "  abreaMapaPau!!!");
	    }    		
		    	
    	
    }
   
    public void limpaBuffer(){
    	buffer = null;
    }
    
    public void DesenhaSe(Graphics2D dbg){
    	if (buffer == null){
    		criaBuffer();
    	}
    	dbg.drawImage(buffer, null, 0, 0);  
    }
    
    public void criaBuffer(){
    	buffer = new BufferedImage(GamePanel.PWIDTH, GamePanel.PHEIGHT, BufferedImage.TYPE_INT_RGB);
    	Graphics2D dbg = buffer.createGraphics();
    	
    	int offx = MapX&0x0f; 
    	int offy = MapY&0x0f;
    	int somax,somay;
    	if(offx>0){
    		somax = 1;
    	}else{
    		somax = 0;
    	}
    	if(offy>0){
    		somay = 1;
    	}else{
    		somay = 0;
    	}
        for(int j = 0; j < NTileY + somay; j++){            
            for(int i = 0; i < NTileX + somax; i++){
            	
                int tilex = (mapa[j+(MapY>>4)][i+(MapX>>4)]%TilePLinhaTileset)<<4;
                int tiley = (mapa[j+(MapY>>4)][i+(MapX>>4)]/TilePLinhaTileset)<<4;
                dbg.drawImage(TileSet,(i<<4)-offx,(j<<4)-offy,(i<<4)+16-offx,(j<<4)+16-offy,tilex,tiley,tilex+16,tiley+16,null);
                
            }
        }
        for(int j = 0; j < NTileY + somay; j++){            
            for(int i = 0; i < NTileX + somax; i++){
            	
                int tilex = (mapa2[j+(MapY>>4)][i+(MapX>>4)]%TilePLinhaTileset)<<4;
                int tiley = (mapa2[j+(MapY>>4)][i+(MapX>>4)]/TilePLinhaTileset)<<4;
                dbg.drawImage(TileSet,(i<<4)-offx,(j<<4)-offy,(i<<4)+16-offx,(j<<4)+16-offy,tilex,tiley,tilex+16,tiley+16,null);
                
            }
        }     
    }
    
    public void Posiciona(int x,int y){
    	int X = x>>4;
    	int Y = y>>4;
    	
        if(X < 0){
            MapX = 0;
        }else if(X >= (Largura-NTileX)){
            MapX = ((Largura-NTileX))<<4;
        }else{
            MapX = x;
           
        }
        
        if(Y < 0){
            MapY = 0;
        }else if(Y >= (Altura-NTileY)){
            MapY = ((Altura-NTileY))<<4;
        }else{
            MapY = y;
        }        

    }
    
    public int ReadCInt(DataInputStream data) throws IOException{
        @SuppressWarnings("unused")
		int dado;
    	int b1 = data.readByte();
    	int b2 = data.readByte(); 
    	int b3 = data.readByte(); 
    	int b4 = data.readByte();                     	
    	
    	return dado = ((int)b1&0x00ff)|(((int)b2&0x00ff)<<8)|(((int)b3&0x00ff)<<16)|(((int)b4&0x00ff)<<24);            	    	
    }
    
    
    public void parseWave(String arqWave){
		listaWaves = new ArrayList<TipoWave>();
		//File file = new File(arqWave);
		InputStream is = GamePanel.instance.getClass().getResourceAsStream("/"+arqWave);
		String str = "";
		quantidadeTotalInimigos =0;
	    try {
//	    	FileInputStream fstream = new FileInputStream(file);
//	        DataInputStream in = new DataInputStream(fstream);
	        BufferedReader dados = new BufferedReader(new InputStreamReader(is)); 
	        while((str = dados.readLine())!=null){
	            if(str.charAt(0)!='#'){
	                TipoWave wave = new TipoWave();
	                String strs[] = str.split(";");
	               // System.out.println(" life linha 318 "+Integer.parseInt(strs[1]));
	                wave.life = Integer.parseInt(strs[1]);
	                wave.velocidade = Integer.parseInt(strs[2]);
	                wave.raio = Integer.parseInt(strs[3]);
	                wave.cadencia = Integer.parseInt(strs[4]);
	                wave.dano = Integer.parseInt(strs[5]);
	                wave.codImgInimigo = Integer.parseInt(strs[6]);
	                wave.qtde = Integer.parseInt(strs[7]);
	                quantidadeTotalInimigos+=wave.qtde;
	                wave.recompensa = Integer.parseInt(strs[8]);
//	                System.out.println("recompensa Wave Recompensa "+ strs[8]);
	                listaWaves.add(wave);
	            }
	        }          
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	}
	
	public void parseCoord(String arqCoord){
		listaPaths = new ArrayList<ArrayList<TipoCoord>>();
		//File file = new File(arqCoord);	
		//System.out.println("File "+file.getName());
		InputStream is = GamePanel.instance.getClass().getResourceAsStream("/"+arqCoord);
		
		String str = "";
	    try {
//	    	FileInputStream fstream = new FileInputStream(file);
//	        DataInputStream in = new DataInputStream(fstream);
	        BufferedReader dados = new BufferedReader(new InputStreamReader(is));
	        ArrayList<TipoCoord> listaCoords1 = new ArrayList<TipoCoord>();
	        ArrayList<TipoCoord> listaCoords2 = new ArrayList<TipoCoord>();
	        while((str = dados.readLine())!=null){
	            if(str.charAt(0)!='#'){
	                TipoCoord coord1 = new TipoCoord();
	                TipoCoord coord2 = new TipoCoord();
	                String strs[] = str.split(";");	                
	                coord1.x = Integer.parseInt(strs[0]);
	                coord1.y = Integer.parseInt(strs[1]);	                
	                listaCoords1.add(coord1);	                
	                if (numPaths >1 && strs.length == 4){
	                	coord2.x = Integer.parseInt(strs[2]);
		                coord2.y = Integer.parseInt(strs[3]);
		                listaCoords2.add(coord2);
	                }
	            }
	        }          
	        listaPaths.add(listaCoords1);
			if (listaCoords2.size() > 0) {
				listaPaths.add(listaCoords2);
			}
	    } catch (IOException e) {
	        e.printStackTrace();
	    }
	}

	public void carregaWave(int nroWave){
		TipoWave wave = listaWaves.get(nroWave);
		BufferedImage imDoInimigo = Constantes.imagensDosInimigos.get(wave.codImgInimigo);
		Constantes.ListaInimigos = new ArrayList<Enemy>();
		int pos[] = {-1, -1};
		int caminhoSorteado = -1;
		for (int i=0; i<wave.qtde; i++){
			ArrayList<TipoCoord> p = null;
			if (this.numPaths > 0) {
				caminhoSorteado = rand.nextInt(numPaths);
				p = listaPaths.get(caminhoSorteado);
			}
			pos[caminhoSorteado]++;
			Enemy inimigo = new Enemy(imDoInimigo, p, pos[caminhoSorteado], wave.life, wave.velocidade, wave.raio, wave.cadencia, wave.dano, wave.recompensa);
			Constantes.ListaInimigos.add(inimigo);
		}
	}
}
